package com.onlyxiahui.common.action.description.handler.impl.parameter;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import org.springframework.core.MethodParameter;

import com.onlyxiahui.common.action.description.DocumentContext;
import com.onlyxiahui.common.action.description.bean.MethodData;
import com.onlyxiahui.common.action.description.bean.ModuleData;
import com.onlyxiahui.common.action.description.bean.ParameterData;
import com.onlyxiahui.common.action.description.enums.annotation.ParameterMapping;
import com.onlyxiahui.common.action.description.enums.data.ParameterType;
import com.onlyxiahui.common.action.description.handler.impl.BaseParameterHandler;
import com.onlyxiahui.common.action.description.util.ActionAnnotationUtil;

/**
 * Description <br>
 * Date 2020-01-07 17:24:27<br>
 * 
 * @author XiaHui [onlovexiahui@qq.com]<br>
 * @since 1.0.0
 */

public class FormParameterHandler extends BaseParameterHandler {

	protected Map<String, String> annotationMap = getAnnotationMap();

	protected String getAnnotation() {
		return ParameterMapping.RequestParam.getAnnotation();
	}

	@Override
	public boolean support(DocumentContext context, ModuleData moduleData, MethodData methodData, Method method, MethodParameter parameter) {

//		Annotation[] mas = (null != method) ? method.getAnnotations() : new Annotation[0];
//		boolean hasGetMapping = ActionAnnotationUtil.hasAnnotation(MethodRequest.GetMapping.getAnnotation(), mas);
//		boolean hasPostMapping = ActionAnnotationUtil.hasAnnotation(MethodRequest.PostMapping.getAnnotation(), mas);
//		boolean hasPutMapping = ActionAnnotationUtil.hasAnnotation(MethodRequest.PutMapping.getAnnotation(), mas);
//		boolean hasDeleteMapping = ActionAnnotationUtil.hasAnnotation(MethodRequest.DeleteMapping.getAnnotation(), mas);
//		boolean hasPatchMapping = ActionAnnotationUtil.hasAnnotation(MethodRequest.PatchMapping.getAnnotation(), mas);
//		boolean hasRequestMapping = ActionAnnotationUtil.hasAnnotation(MethodRequest.RequestMapping.getAnnotation(), mas);
//
//		boolean supportMethod = hasRequestMapping || hasGetMapping || hasPostMapping || hasPutMapping || hasDeleteMapping || hasPatchMapping;
		Annotation[] as = (null != parameter) ? parameter.getParameterAnnotations() : new Annotation[0];
		boolean has = has(as);
		return has;
	}

	@Override
	public ParameterData handle(DocumentContext context, ModuleData moduleData, MethodData methodData, Method method, MethodParameter parameter) {
		ParameterData pd = handle(context, moduleData, methodData, method, parameter, () -> {
			Annotation[] mas = parameter.getParameterAnnotations();
			String name = getName(mas);
			return null != name ? name : super.getParameterName(context, moduleData, methodData, method, parameter);
		}, (ParameterData p) -> {

		});
		pd.setParameterType(ParameterType.item.type());
		return pd;
	}

	private Map<String, String> getAnnotationMap() {
		Map<String, String> map = new HashMap<>();
		// map.put("org.springframework.web.bind.annotation.PathVariable", "value");
		map.put("org.springframework.web.bind.annotation.ModelAttribute", "value");
		// map.put("org.springframework.web.bind.annotation.RequestParam", "value");
		map.put("org.springframework.web.bind.annotation.RequestHeader", "value");
		map.put("org.springframework.web.bind.annotation.RequestPart", "value");
		return map;
	}

	private boolean has(Annotation[] mas) {
		boolean has = false;
		for (Map.Entry<String, String> e : annotationMap.entrySet()) {
			String a = e.getKey();
			has = ActionAnnotationUtil.hasAnnotation(a, mas);
			if (has) {
				break;
			}
		}
		return has;
	}

	private String getName(Annotation[] mas) {
		String name = null;
		for (Map.Entry<String, String> e : annotationMap.entrySet()) {
			String a = e.getKey();
			String v = e.getValue();
			Object value = ActionAnnotationUtil.getValue(a, v, mas);
			if (null != value) {
				name = value.toString();
				break;
			}
		}
		return name;
	}
}
